﻿using System.Collections.Specialized;
using System.Text;

namespace Azalea.ORMap
{
    public class DbInfo : IDbInfo
    {
        private readonly NameValueCollection _nameValues = new NameValueCollection();
        private DatabaseTypes _dbType;

        #region IDbInfo Members

        public IDbInfo DbType(DatabaseTypes dbType)
        {
            _dbType = dbType;
            return this;
        }

        public IDbInfo DataSource(string dataSource)
        {
            return OtherNameValue("data source", dataSource);
        }

        public IDbInfo InitialCatalog(string initialCatalog)
        {
            return OtherNameValue("initial catalog", initialCatalog);
        }

        public IDbInfo UserId(string userId)
        {
            return OtherNameValue("user id", userId);
        }

        public IDbInfo Password(string password)
        {
            return OtherNameValue("password", password);
        }

        public IDbInfo IntegragedSecurity(string integragedSecurity)
        {
            return OtherNameValue("integrated security", integragedSecurity);
        }

        public IDbInfo OtherNameValue(string name, string value)
        {
            _nameValues[name.ToLower()] = value;
            return this;
        }

        public IDbInfo StandardSqlServer(string dataSource, string initialCatalog, string userId, string password)
        {
            DbType(DatabaseTypes.SqlServer);
            DataSource(dataSource);
            InitialCatalog(initialCatalog);
            UserId(userId);
            Password(password);
            return this;
        }

        public IDbInfo StandardOracle(string dataSource, string userId, string password)
        {
            DbType(DatabaseTypes.Oracle);
            DataSource(dataSource);
            UserId(userId);
            Password(password);
            return this;
        }

        public IDbInfo StandardOracleWithoutDSN(string host, int port, string serviceName, string userId,
                                                string password)
        {
            DbType(DatabaseTypes.Oracle);
            DataSource(
                string.Format(
                    "(description=(address=(protocol=tcp)(host={0})(port={1}))(connect_data=(service_name={2})))",
                    host, port, serviceName));
            UserId(userId);
            Password(password);
            return this;
        }

        public IDbInfo StandardOdbcExcel(string file)
        {
            DbType(DatabaseTypes.Odbc);
            OtherNameValue("driver", "{Microsoft Excel Driver (*.xls)}");
            OtherNameValue("dbq", file);
            return this;
        }

        public IDbInfo StandardOdbcAccess(string file)
        {
            DbType(DatabaseTypes.Odbc);
            OtherNameValue("driver", "{Microsoft Access Driver (*.mdb)}");
            OtherNameValue("dbq", file);
            return this;
        }

        public IDbInfo StandardSqlite(string file)
        {
            DbType(DatabaseTypes.Sqlite);
            DataSource(file);
            return this;
        }

        public DatabaseTypes GetDbType()
        {
            return _dbType;
        }

        public string GetConnectionString()
        {
            var sb = new StringBuilder();
            foreach (string key in _nameValues.Keys)
            {
                sb.Append(key);
                sb.Append("=");
                sb.Append(_nameValues[key]);
                sb.Append(";");
            }
            return sb.ToString();
        }

        #endregion

        public override string ToString()
        {
            return GetConnectionString();
        }
    }
}